﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Derbster.Domain
{
    public enum PlayerState
    {
        Ready,
        InQueue,
        InBox,
        FouledOut,
        Ejected
    }

    public class Player : IEquatable<Player>
    {
        [ContractVerification(false)]
        internal Player()
        {
            
        }

        public Player(Skater skater)
        {
            Contract.Requires(skater != null);
            Skater = skater;
            State = PlayerState.Ready;
        }

        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int PlayerId { get; internal set; }
        public Roster Roster { get; internal set; }
        public Skater Skater { get; internal set; }
        public PlayerState State { get; internal set; }
        public bool IsCaptain { get; internal set; }

        public bool Equals(Player other)
        {
            Contract.Assume(((((null == other || this == other) || this.State != other.State) 
                || this.IsCaptain != other.IsCaptain) || this.Roster != null));

            if (ReferenceEquals(null, other))
            {
                return false;
            }
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            return State == other.State 
                && IsCaptain.Equals(other.IsCaptain)
                && this.Roster.Color.Equals(other.Roster.Color)
                && Skater.Number.Equals(other.Skater.Number);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            if (obj.GetType() != this.GetType())
            {
                return false;
            }
            return Equals((Player)obj);
        }

        public override int GetHashCode()
        {
            Contract.Assume(this.Roster != null);
            Contract.Assume(this.Roster.Color != null);
            Contract.Assume(this.Skater != null);
            Contract.Assume(this.Skater.Number != null);
            unchecked
            {
                int hashCode = this.Roster.Color.GetHashCode();
                hashCode = (hashCode * 397) ^ this.Skater.Number.GetHashCode();
                hashCode = (hashCode * 397) ^ this.IsCaptain.GetHashCode();

                return hashCode;
            }
        }
    }
}
